﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Space_Conquest
{
    class MapArea
    {

        #region Private Members

        private int _x;
        private int _y;
        private int _width;
        private int _height; 

        #endregion

        #region Constructors

        public MapArea(int x, int y, int width, int height)
        {

            _x = x;
            _y = y;
            _height = height;
            _width = width;

        } 

        #endregion

        #region Properties

        public int X
        {
            get
            {
                return _x;
            }
            set
            {
                _x = value;
            }
        }

        public int Y
        {
            get
            {
                return _y;
            }
            set
            {
                _y = value;
            }
        }

        public int Width
        {
            get
            {
                return _width;
            }
            set
            {
                _width = value;
            }
        }

        public int Height
        {
            get
            {
                return _height;
            }
            set
            {
                _height = value;
            }
        }

        #endregion

        #region Methods

        public bool IsAdjacentTo(MapPoint secondPoint)
        {

            var adjacentPoints = GetListOfAdjacentMapPoints();
            foreach (MapPoint p in adjacentPoints)
            {
                if (p.Equals(secondPoint))
                    return true;
            }

            return false;

        }

        public bool IsAdjacentTo(MapArea secondArea)
        {


            List<MapPoint> mapPoints = GetListOfAllMapPoints();
            List<MapPoint> adjacentPoints = secondArea.GetListOfAdjacentMapPoints();

            foreach (MapPoint p2 in adjacentPoints)
            {
                foreach (MapPoint p1 in mapPoints)
                {
                    if (p1.Equals(p2))
                    {
                        return true;
                    }
                }
            }

            return false;

        }

        public List<MapPoint> GetListOfAllMapPoints()
        {

            List<MapPoint> temp = new List<MapPoint>();

            for (int j = _y; j < _y + _height; ++j)
            {
                for (int i = _x; i < _x + _width; ++i)
                {
                    temp.Add(new MapPoint(i,j));
                }
            }

            return temp;

        }

        public List<MapPoint> GetListOfAdjacentMapPoints()
        {

            List<MapPoint> temp = new List<MapPoint>();

            for(int i = _x; i < _x + _width; ++i)
            {
                temp.Add(new MapPoint(i, _y - 1));
                temp.Add(new MapPoint(i, _y + _height)); 
            }

            for (int j = _y; j < _y + _height; ++j)
            {
                temp.Add(new MapPoint(_x - 1, j));
                temp.Add(new MapPoint(_x + _width, j));
            }

            return temp;

        }

        public MapPoint GetClosestAdjacentPoint(MapPoint sourcePoint)
        {

            List<MapPoint> adjacentPoints = GetListOfAdjacentMapPoints();

            double minimumDistance = 0;
            MapPoint returnPoint = null;

            foreach (MapPoint point in adjacentPoints)
            {

                if (minimumDistance == 0)
                {
                    minimumDistance = sourcePoint.DistanceBetween(point);
                    returnPoint = new MapPoint(point.X, point.Y);
                }
                else
                {
                    if (sourcePoint.DistanceBetween(point) < minimumDistance)
                    {
                        minimumDistance = sourcePoint.DistanceBetween(point);
                        returnPoint = new MapPoint(point.X, point.Y);
                    }
                }

            }

            return returnPoint;

        }

        public MapPoint GetScalarPoint()
        {
 
                return new MapPoint(_x, _y);

        }

        public Unit FindClosestUnit(Unit[] unitList)
        {

            double minimimDistance = 100000;
            Unit currentClosestUnit = null;

            foreach (Unit unit in unitList)
            {
                if (GetScalarPoint().DistanceBetween(unit.MapPoint) < minimimDistance)
                {
                    minimimDistance = GetScalarPoint().DistanceBetween(unit.MapPoint);
                    currentClosestUnit = unit;
                }
            }

            return currentClosestUnit;

        }

        #endregion

    }
}
